import sys

sys.path.append("./lib")

import yaml, plugins, helpers

class Workflow(object):
    def __init__(self, filename):
        yamlDoc = yaml.load(open(filename, 'r'))
        self.__inputs = yamlDoc['inputs']
        self.__outputs = yamlDoc['outputs']
        self.__operations = yamlDoc['operations']
        self.__title = yamlDoc['title']
        self.__mode = yamlDoc['mode']
        self.__fromString = {'alpha': str, 'binary': helpers.binary_to_decimal}[self.__mode]
        self.__toString = {'alpha': str, 'binary': helpers.decimal_to_binary}[self.__mode]

    @property
    def title(self):
        return self.__title
    
    @property
    def operations(self):
        return self.__operations
    
    @property
    def inputs(self):
        return self.__inputs

    @property
    def outputs(self):
        return self.__outputs

    def steps(self, inputs):
        """
        Runs the workflow step-by-step. Provides an iterator.

        Input: A dictionary of inputs.
        Output: A dictionary of outputs.
        """
        for k,v in inputs.items():
            try:
                exec "%s = %s" % (k, self.__fromString(v))
            except ValueError:
                raise ValueError("Invalid input, %s must be %s." % (k, self.__mode), k)
        for op in self.__operations:
            results = {}
            inputs = ", ".join(op['inputs'])
            outputs = ", ".join(op['outputs'])
            exec "%s = plugins.%s(%s)" % (outputs, op['name'], inputs)
            for i in op['outputs']:
                exec "temp = %s" % i
                results[i] = self.__toString(temp)
            yield results
